/*************************************************************************
	> File Name: cancel_async.c
	> Author: 
	> Mail: 
	> Created Time: 2015年01月18日 星期日 22时33分51秒
 ************************************************************************/

#include<pthread.h>
#include"errors.h"

#define SIZE 10

static int matrixa[SIZE][SIZE];
static int matrixb[SIZE][SIZE];
static int matrixc[SIZE][SIZE];

void *thread_routine(void *arg){
    int cancel_type,status;
    int i,j,k;
    int value = 1;
    
    // Initialize the matrices
    for(i = 0;i < SIZE;i++){
        for(j = 0;j < SIZE;j++){
            matrixa[i][j] = i;
            matrixb[i][j] = j;
        }
    }
    show_matrix(matrixa);
    show_matrix(matrixb);

    while(1){
        // compute the matrix product of matrixa and matrixb.

        status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&cancel_type);
        if(status) err_abort(status,"Set cancel type");
        for(i = 0;i < SIZE;i++){
            for(j = 0;j < SIZE;j++){
                matrixc[i][j] = 0;
                for(k = 0;k < SIZE;k++){
                    matrixc[i][j] += matrixa[i][k] * matrixb[k][j];
                }
            }
        }
        status = pthread_setcanceltype(cancel_type,&cancel_type);
        if(status) err_abort(status, "Set cancel type");
        
        //copy the result (matrixc) into matrixa to start arain
        for(i = 0;i < SIZE;i++){
            for(j = 0;j < SIZE;j++){
                matrixa[i][j] = matrixc[i][j];
            }
        }
    }
}

int show_matrix(int (*m)[SIZE]){
    int i,j;

    for(i = 0;i < SIZE;i++){
        for(j = 0;j < SIZE;j++){
            printf("%d ",*(*(m + i) + j));
        }
        putchar('\n');
    }
}


int main(int argc,char *argv[]){
    pthread_t thread_id;
    void * result;
    int status;

    status = pthread_create(&thread_id,NULL,thread_routine,NULL);
    if(status) err_abort(status,"Create thread:");

    sleep(1);
    status = pthread_cancel(thread_id);
    if(status) err_abort(status, "Cancel thread id");

    status = pthread_join(thread_id,&result);
    if(status) err_abort(status, "Join thread");
    
    if(result == PTHREAD_CANCELED){
        printf("Thread canceled\n");
    }else{
        printf("Thread was not canceled\n");
    }
    show_matrix(matrixa);
    show_matrix(matrixb);
    show_matrix(matrixc);
    return 0;
}

